package pe.com.cotelasa.scp.controlador;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.context.annotation.Scope;

import org.apache.log4j.Logger;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import pe.com.cotelasa.common.controlador.MBGenerico;
import pe.com.cotelasa.scp.controlador.backingBean.BKDetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.controlador.backingBean.BKOrdenServicio;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioArchivos;
import pe.com.cotelasa.scp.dominio.service.IServicioTipoUnidadMinima;
import pe.com.cotelasa.scp.dominio.service.IServicioDetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.dominio.service.IServicioProveedorArticulo;
import pe.com.cotelasa.scp.dominio.service.IServicioArticulo;
import pe.com.cotelasa.scp.dominio.service.IServicioTipoMoneda;
import pe.com.cotelasa.scp.dominio.excepcion.ServiceException;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioNumeroALetras;
import pe.com.cotelasa.scp.entidad.Articulo;
import pe.com.cotelasa.scp.entidad.DetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.entidad.PartidaDespacho;
import pe.com.cotelasa.seguridad.controlador.backingBean.BKSession;

/**
 *
 * @author usuario
 */
@Named(value = "MBDetalleOrdenServicio")
@Scope("request")
public class MBDetalleOrdenServicio extends MBGenerico implements Serializable {

    private static Logger logger = Logger.getLogger(MBOrdenServicio.class);
    @Inject
    private BKDetalleOrdenCompraServicio bkDetalleOrdenServicio;
    @Inject
    private BKOrdenServicio bkOrdenServicio;
    @Inject
    private IServicioTipoUnidadMinima servicioTipoUnidadMinima;
    @Inject
    private IServicioArticulo servicioArticulo;
    @Autowired
    BKSession session;

    public MBDetalleOrdenServicio() {
    }

    private String generateAuthCode() {
        System.out.println("Entering generateAuthCode()");
        //getting the current time in nanoseconds
        long decimalNumber = System.nanoTime();
        System.out.println("current time in nanoseconds: " + decimalNumber);

        //To convert time stamp to alphanumeric code.
        //We need to convert base10(decimal) to base36
        String strBaseDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String strTempVal = "";
        int mod = 0;
        int authCodeLength = 0;
        // String concat is costly, instead we could have use stringbuffer or stringbuilder
        //but here it wont make much difference.
        while (decimalNumber != 0 && authCodeLength < 8) {
            mod = (int) (decimalNumber % 36);
            strTempVal = strBaseDigits.substring(mod, mod + 1) + strTempVal;
            decimalNumber = decimalNumber / 36;
            authCodeLength++;
        }
        System.out.println("alphanumeric code generated from TimeStamp : " + strTempVal);
        return strTempVal;

    }

    public void nuevoDetalle(ActionEvent actionEvent) {

        bkDetalleOrdenServicio.setDetalleOrdenCSFormulario(new DetalleOrdenCompraServicio());

        bkDetalleOrdenServicio.setIdTipoUnidadMinimaFormulario(null);
        bkDetalleOrdenServicio.setImagenDetalle(null);
        bkDetalleOrdenServicio.setIdArticuloFormulario(null);
        bkDetalleOrdenServicio.setTipoAccion('a');
        bkDetalleOrdenServicio.getDetalleOrdenCSFormulario().setTotalRecibido(BigDecimal.ZERO);
        try {
            if (bkDetalleOrdenServicio.getListaTipoUnidadMinima() == null) {
                bkDetalleOrdenServicio.setListaTipoUnidadMinima(servicioTipoUnidadMinima.listarTipoUnidadMinimasActivos());
            }


            //if (bkOrdenServicio.getListaDetalleOrdenCompraServicio() == null || bkDetalleOrdenServicio.getListaArticulo() == null) {

            bkDetalleOrdenServicio.setListaArticulo(new ArrayList<Articulo>());
            for (Articulo art : bkOrdenServicio.getListaArticuloCat()) {
                Articulo articulo = servicioArticulo.conseguirArticuloPorId(art.getId());
                bkDetalleOrdenServicio.getListaArticulo().add(articulo);
            }
            //}
            if (bkOrdenServicio.getListaDetalleOrdenCompraServicio() != null) {
                if (!bkOrdenServicio.getListaDetalleOrdenCompraServicio().isEmpty()) {
                    for (DetalleOrdenCompraServicio det : bkOrdenServicio.getListaDetalleOrdenCompraServicio()) {
                        if (bkDetalleOrdenServicio.getListaArticulo().contains(det.getIdArticulo())) {
                            bkDetalleOrdenServicio.getListaArticulo().remove(det.getIdArticulo());
                        }
                    }
                }
            }

        } catch (ServiceException e) {
            mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
            logger.error(e.getMessage(), e);
        }

    }

    public void editarDetalle() {
        bkDetalleOrdenServicio.setEliminarImagen(false);
        try {
            DetalleOrdenCompraServicio detalle = bkDetalleOrdenServicio.getDetalleOrdenCSFormulario();
            bkDetalleOrdenServicio.setDetalleOrdenCSSeleccionado(detalle);
            bkDetalleOrdenServicio.setIdArticuloFormulario(servicioArticulo.conseguirArticuloPorId(detalle.getIdArticulo().getId()));
            bkDetalleOrdenServicio.setIdTipoUnidadMinimaFormulario(detalle.getIdTipoUnidadMinima().getId());
            bkDetalleOrdenServicio.setImagenDetalle(null);
            bkDetalleOrdenServicio.setTipoAccion('e');
            if (bkDetalleOrdenServicio.getListaTipoUnidadMinima() == null) {
                bkDetalleOrdenServicio.setListaTipoUnidadMinima(servicioTipoUnidadMinima.listarTipoUnidadMinimasActivos());
            }

            //if (bkDetalleOrdenServicio.getListaArticulo() == null) {
            bkDetalleOrdenServicio.setListaArticulo(new ArrayList<Articulo>());
            for (Articulo art : bkOrdenServicio.getListaArticuloCat()) {
                Articulo articulo = servicioArticulo.conseguirArticuloPorId(art.getId());
                bkDetalleOrdenServicio.getListaArticulo().add(articulo);
            }

            //}
            for (DetalleOrdenCompraServicio det : bkOrdenServicio.getListaDetalleOrdenCompraServicio()) {
                Iterator itr = this.bkDetalleOrdenServicio.getListaArticulo().iterator();

                while (itr.hasNext()) {
                    Articulo art = (Articulo) itr.next();
                    if (det.getIdArticulo().equals(art)) {
                        itr.remove();
                        break;
                    }
                }

            }
            bkDetalleOrdenServicio.getListaArticulo().add(bkDetalleOrdenServicio.getIdArticuloFormulario());

        } catch (ServiceException e) {
            mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
            logger.error(e.getMessage(), e);
        }
    }

    public void agregarListaDetalles(ActionEvent actionEvent) {

        DetalleOrdenCompraServicio detalle = bkDetalleOrdenServicio.getDetalleOrdenCSFormulario();

        if (bkOrdenServicio.getOrdenServicioFormulario().getCrearPartidas() == 1) {
            detalle.setCantidad(BigDecimal.ZERO);

            if (detalle.getPartidaDespachoCollection() != null) {
                for (PartidaDespacho partida1 : detalle.getPartidaDespachoCollection()) {
                    if (partida1.getEstadoRegistro() == ESTADO_REGISTRO.ACTIVO.getValor()) {
                        detalle.setCantidad(detalle.getCantidad().add(partida1.getCantidad()));
                    }

                }
            }

        }

        detalle.setCantidadForm(detalle.getCantidad());

        BigDecimal subtotal = detalle.getCantidad().multiply(detalle.getPrecio());

        BigDecimal igv = bkDetalleOrdenServicio.getIgvFormulario().getMonto().divide(BigDecimal.valueOf(100));

        if (bkDetalleOrdenServicio.getEstadoIgvFormulario() == 's') {
            detalle.setSubTotal(subtotal);
        } else {
            detalle.setPrecio(detalle.getPrecio().divide(igv.add(BigDecimal.ONE), MathContext.DECIMAL32));
            detalle.setSubTotal(subtotal.divide(igv.add(BigDecimal.ONE), MathContext.DECIMAL32));
        }
        detalle.setPrecioForm(detalle.getPrecio());

        if (bkOrdenServicio.getListaDetalleOrdenCompraServicio() == null) {
            bkOrdenServicio.setListaDetalleOrdenCompraServicio(new ArrayList<DetalleOrdenCompraServicio>());
            //bkOrdenServicio.setListaTemporalDetalleOrdenCompraServicio(new ArrayList<DetalleOrdenCompraServicio>());
        }

        try {
            detalle.setIdArticulo(bkDetalleOrdenServicio.getIdArticuloFormulario());
            detalle.setEstadoRegistro(ESTADO_REGISTRO.ACTIVO.getValor());
            detalle.setNombreArticulo(detalle.getIdArticulo().getNombreComercial());
            detalle.setIdTipoUnidadMinima(servicioTipoUnidadMinima.conseguirTipoUnidadMinimaPorId(bkDetalleOrdenServicio.getIdTipoUnidadMinimaFormulario()));
            detalle.setUnidadMedidaForm(detalle.getIdTipoUnidadMinima().getAbrev());
            String ext = "";
            if (bkDetalleOrdenServicio.getTipoAccion() == 'a') {
                detalle.setUsrCreacion(session.getUsuario().getUsuario());
                detalle.setFecCreacion(new Date());

                if (bkDetalleOrdenServicio.getImagenDetalle() != null) {
                    String[] imagen = StringUtils.split(bkDetalleOrdenServicio.getImagenDetalle().getFileName(), ".");
                    String nombre = generateAuthCode();
                    ext = imagen[imagen.length - 1];
                    detalle.setImagen(nombre + "." + ext);
                } else {
                    detalle.setImagen(null);
                }

                bkOrdenServicio.getListaDetalleOrdenCompraServicio().add(detalle);
                bkOrdenServicio.getListaTemporalDetalleOrdenCompraServicio().add(detalle);
                if (bkDetalleOrdenServicio.getImagenDetalle() != null) {
                    guardarImagenServer(bkDetalleOrdenServicio.getImagenDetalle(), serviceProperties.getProperty("path.server.imagen.ordenCS")
                            + detalle.getImagen());
                }

            } else {
                detalle.setUsrModificacion(session.getUsuario().getUsuario());
                detalle.setFecModificacion(new Date());

                if (bkDetalleOrdenServicio.getImagenDetalle() != null) {
                    String[] imagen = StringUtils.split(bkDetalleOrdenServicio.getImagenDetalle().getFileName(), ".");
                    ext = imagen[imagen.length - 1];
                    if (detalle.getImagen() == null) {
                        String nombre = generateAuthCode();
                        detalle.setImagen(nombre + "." + ext);
                    }
                }

                Integer i = bkOrdenServicio.getListaDetalleOrdenCompraServicio().indexOf(bkDetalleOrdenServicio.getDetalleOrdenCSSeleccionado());

                Integer j = bkOrdenServicio.getListaTemporalDetalleOrdenCompraServicio().indexOf(bkDetalleOrdenServicio.getDetalleOrdenCSSeleccionado());

                if (bkDetalleOrdenServicio.getImagenDetalle() != null) {
                    guardarImagenServer(bkDetalleOrdenServicio.getImagenDetalle(), serviceProperties.getProperty("path.server.imagen.ordenCS")
                            + detalle.getImagen());
                } else {
                    if (bkDetalleOrdenServicio.isEliminarImagen()) {
                        eliminarImagenServer(serviceProperties.getProperty("path.server.imagen.ordenCS") + detalle.getImagen());
                        detalle.setImagen(null);
                    }
                }

                bkOrdenServicio.getListaDetalleOrdenCompraServicio().set(i, detalle);
                bkOrdenServicio.getListaTemporalDetalleOrdenCompraServicio().set(j, detalle);

            }
            CalcularTotales(bkOrdenServicio.getListaDetalleOrdenCompraServicio());
            armarDescripcionOC(bkOrdenServicio.getListaDetalleOrdenCompraServicio());

        } catch (ServiceException e) {
            mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
            logger.error(e.getMessage(), e);
        }


    }

    public void eliminarDetalle(ActionEvent actionEvent) {

        DetalleOrdenCompraServicio detalleOrdenServicio = bkDetalleOrdenServicio.getDetalleOrdenCSSeleccionado();

        if (detalleOrdenServicio.getId() != null) {
            bkOrdenServicio.getListaDetalleOrdenCompraServicio().remove(detalleOrdenServicio);
            Integer i = bkOrdenServicio.getListaTemporalDetalleOrdenCompraServicio().indexOf(detalleOrdenServicio);

            detalleOrdenServicio.setFecModificacion(new Date());
            detalleOrdenServicio.setUsrModificacion(session.getUsuario().getUsuario());
            detalleOrdenServicio.setEstadoRegistro(ESTADO_REGISTRO.INACTIVO.getValor());

            bkOrdenServicio.getListaTemporalDetalleOrdenCompraServicio().set(i, detalleOrdenServicio);
        } else {
            Iterator itr = this.bkOrdenServicio.getListaDetalleOrdenCompraServicio().iterator();
            while (itr.hasNext()) {
                DetalleOrdenCompraServicio det = (DetalleOrdenCompraServicio) itr.next();
                if (detalleOrdenServicio.getIdArticulo().getId().equals(det.getIdArticulo().getId())) {
                    itr.remove();
                    break;
                }
            }
            Iterator itr1 = this.bkOrdenServicio.getListaTemporalDetalleOrdenCompraServicio().iterator();
            if (bkOrdenServicio.getComando().getNombre().equals("Actualizar")) {
                while (itr1.hasNext()) {

                    DetalleOrdenCompraServicio det = (DetalleOrdenCompraServicio) itr1.next();
                    if (detalleOrdenServicio.getIdArticulo().equals(det.getIdArticulo())
                            && det.getEstadoRegistro() == ESTADO_REGISTRO.ACTIVO.getValor()) {
                        itr1.remove();
                        break;
                    }
                }
            }
        }


        CalcularTotales(bkOrdenServicio.getListaDetalleOrdenCompraServicio());
        armarDescripcionOC(bkOrdenServicio.getListaDetalleOrdenCompraServicio());

        if (bkOrdenServicio.getListaDetalleOrdenCompraServicio().isEmpty()) {
            bkOrdenServicio.setListaDetalleOrdenCompraServicio(null);
        }

    }

    public void CalcularTotales(List<DetalleOrdenCompraServicio> listaDetalle) {
        BigDecimal subtotal = BigDecimal.ZERO;
        BigDecimal cantidadTotal = BigDecimal.ZERO;
        String um = "";
        for (DetalleOrdenCompraServicio detalle : listaDetalle) {
            subtotal = subtotal.add(detalle.getSubTotal());
            cantidadTotal = cantidadTotal.add(detalle.getCantidad());
            if(um.equalsIgnoreCase("")){
                um = detalle.getIdTipoUnidadMinima().getAbrev();
            }
        }
        bkOrdenServicio.getOrdenServicioFormulario().setCantidadTotal(cantidadTotal);
        bkOrdenServicio.getOrdenServicioFormulario().setUnidad(um);
        bkOrdenServicio.getOrdenServicioFormulario().setSubtotal(subtotal);

        //try {
        bkOrdenServicio.getOrdenServicioFormulario().setIgv(
                bkDetalleOrdenServicio.getIgvFormulario().getMonto().divide(BigDecimal.valueOf(100)).multiply(subtotal));
        bkOrdenServicio.getOrdenServicioFormulario().setTotal(
                bkOrdenServicio.getOrdenServicioFormulario().getIgv().add(subtotal));
        UtilitarioNumeroALetras util = new UtilitarioNumeroALetras();
        DecimalFormat decf = new DecimalFormat("###.##");

        bkOrdenServicio.getOrdenServicioFormulario().setExpresionTotal(
                util.Convertir("" + decf.format(bkOrdenServicio.getOrdenServicioFormulario().getTotal()), true, bkOrdenServicio.getOrdenServicioFormulario().getIdTipoMoneda().getNombre()));
        /*} catch (ServiceException e) {
         mostrarError("Ocurrieron algunos problemas al cargar la informacion. Vuelva a intentar.");
         logger.error(e.getMessage(), e);
         }*/
    }

    public void armarDescripcionOC(List<DetalleOrdenCompraServicio> listaDetalle) {
        bkOrdenServicio.getOrdenServicioFormulario().setDescripcion("");

        for (DetalleOrdenCompraServicio detalle : listaDetalle) {
            bkOrdenServicio.getOrdenServicioFormulario().setDescripcion(
                    bkOrdenServicio.getOrdenServicioFormulario().getDescripcion() + detalle.getIdArticulo().getNombreComercial() + " ");
        }

    }

    public void handleFileUpload(FileUploadEvent event) {
        bkDetalleOrdenServicio.setImagenDetalle(event.getFile());
        FacesMessage msg = new FacesMessage("Se subió la foto satisfactoriamente", event.getFile().getFileName());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    private boolean guardarImagenServer(UploadedFile fileLogo, String logo) throws ServiceException {
        try {
            File archivoLogo = new File(logo);
            if (archivoLogo != null) {
                if (archivoLogo.exists()) {
                    UtilitarioArchivos.delete(archivoLogo);
                }
            }
            UtilitarioArchivos.copyInputStream(fileLogo.getInputstream(), archivoLogo);
            return true;
        } catch (IOException e) {
            throw new ServiceException(e);
        }

    }

    private boolean eliminarImagenServer(String logo) throws ServiceException {
        try {
            File archivoLogo = new File(logo);
            if (archivoLogo != null) {
                if (archivoLogo.exists()) {
                    UtilitarioArchivos.delete(archivoLogo);
                }
            }
            return true;
        } catch (IOException e) {
            throw new ServiceException(e);
        }

    }
}
